Linux 系统调用过程详细分析
内核版本:Linux-4.19
操作系统通过系统调用为运行于其上的进程提供服务。
那么,在应用程序内,调用一个系统调用的流程是怎样的呢?
我们以一个假设的系统调用 xyz() 为例,介绍一次系统调用的所有环节。
如上图所示,系统调用执行的流程如下:
1. 应用程序代码调用 xyz(),该函数是一个包装系统调用的库函数; 2. 库函数 xyz() 负责准备向内核传递的参数,并触发软中断以切换到内核; 3. CPU 被软中断打断后,执行中断处理函数,即系统调用处理函数(system_call); 4. 系统调用处理函数调用系统调用服务例程(sys_xyz ),真正开始处理该系统调用。系统调用的实现来自于Glibc,几乎所有 C 程序都要调用 Glibc 的动态链接库 libc.so 中的库函数。这些库函数的源码是不可见的,可通过 objdump 或 gdb 等工具对代码进行汇编反编译,摸清大体的过程。
我们可不必太过纠结,知道原理就好。
下面继续分析在内核中的实现过程。
Pure EABI user space always put syscall number into scno (r7).
当从用户态转为内核态时,系统会将 syscall number 存储在寄存器 R7 中,利用 R7 来传参。
在 entry-header.S 文件中,有如下代码:
scno .req r7 @ syscall number tbl .req r8 @ syscall table pointer why .req r8 @ Linux syscall (!= 0) tsk .req r9 @ current thread_info类似于给寄存器起了个“别名”。
最后通过
invoke_syscall tbl, scno, r10, __ret_fast_syscall
代码成功调用 syscall table 中的服务程序。
invoke_syscall 定义如下: .macro invoke_syscall, table, nr, tmp, ret, reload=0 #ifdef CONFIG_CPU_SPECTRE mov \tmp, \nr cmp \tmp, #NR_syscalls @ check upper syscall limit movcs \tmp, #0 csdb badr lr, \ret @ return address .if \reload add r1, sp, #S_R0 + S_OFF @ pointer to regs ldmccia r1, {r0 - r6} @ reload r0-r6 stmccia sp, {r4, r5} @ update stack arguments .endif ldrcc pc, [\table, \tmp, lsl #2] @ call sys_IT之家 routine #else cmp \nr, #NR_syscalls @ check upper syscall limit badr lr, \ret @ return address .if \reload add r1, sp, #S_R0 + S_OFF @ pointer to regs ldmccia r1, {r0 - r6} @ reload r0-r6 stmccia sp, {r4, r5} @ update stack arguments .endif ldrcc pc, [\table, \nr, lsl #2] @ call sys_IT之家 routine #endif .endm回看
invoke_syscall tbl, scno, r10, __ret_fast_syscall
这段代码。tbl 是指向的何处呢?
接下来,就简单的介绍一下 syscall table 这个表是怎样形成的。
查看代码我们发现,tbl 表示 sys_call_table 的地址:
adr tbl, sys_call_table @ load syscall table pointer
entry-common.S 中有这样一段代码: syscall_table_start sys_call_table #define COMPAT(nr, native, compat) syscall nr, native #ifdef CONFIG_AEABI #include <calls-eabi.S> #else #include <calls-oabi.S> #endif #undef COMPAT syscall_table_end sys_call_table calls-eabi.S 文件内容如下: NATIVE(0, sys_restart_syscall) NATIVE(1, sys_exit) NATIVE(2, sys_fork) NATIVE(3, sys_read) NATIVE(4, sys_write) NATIVE(5, sys_open) NATIVE(6, sys_close) NATIVE(8, sys_creat) NATIVE(9, sys_link) NATIVE(10, sys_unlink) NATIVE(11, sys_execve) NATIVE(12, sys_chdir) NATIVE(14, sys_mknod) NATIVE(15, sys_chmod) NATIVE(16, sys_lchown16) NATIVE(19, sys_lseek) NATIVE(20, sys_getpid) ... 以上代码中宏的定义如下: /IT之家 定义 sys_call_table,并将 __sys_nr 清 0 IT之家/ .macro syscall_table_start, sym .equ __sys_nr, 0 .type \sym, #object ENTRY(\sym) .endm /IT之家 检查序号错误,并利用 sys_ni_syscall 填充缺少的序号 IT之家/ .macro syscall, nr, func .ifgt __sys_nr - \nr .error "Duplicated/unorded system call entry" .endif .rept \nr - __sys_nr .long sys_ni_syscall .endr .long \func .equ __sys_nr, \nr + 1 .endm /IT之家 检查序号是否超过了 __NR_syscalls,如果不足的话,用 sys_ni_syscall 来填充 IT之家/ .macro syscall_table_end, sym .ifgt __sys_nr - __NR_syscalls .error "System call table too big" .endif .rept __NR_syscalls - __sys_nr .long sys_ni_syscall .endr .size \sym, . - \sym .endm /IT之家 NATIVE 宏定义 IT之家/ #define NATIVE(nr, func) syscall nr, func到这里应该分析完了系统调用的大概过程,感谢大家花费宝贵的时间浏览,如果有什么问题欢迎探讨,后期会进行修改和补充!
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/server/jiqiao/8812.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
EasyDSS RTMP流媒体服务器运
时间:2021-01-07
-
Linux客户端访问NFS报Permi
时间:2021-01-07
-
MobaXterm中运行脚本出现c
时间:2021-01-07
-
解决启动Nginx出现"'THRE
时间:2020-12-29
-
centeros7的redis-cli命令不生
时间:2020-12-29
-
本地java链接远程服务器
时间:2020-12-29
-
在不重启的情况下为Vmwa
时间:2020-12-28
-
英特尔修复Linux CPU漏洞:
时间:2020-12-28
热门文章
-
4种绕过Linux/Unix命令别名的方法
时间:2020-12-26
-
如何检查你的计算机使用的是UEFI还是BI
时间:2020-12-26
-
在Linux下为X1 Carbon CPU降压
时间:2020-12-26
-
为你的Fedora系统增添发音功能
时间:2020-12-28
-
英特尔修复Linux CPU漏洞:19年前的奔腾3也
时间:2020-12-28
-
使用molly-guard保护你的Linux/Unix机器不会被
时间:2020-12-28
-
解决启动Nginx出现"'THREAD_CONCURRENCY' is d
时间:2020-12-29
-
本地java链接远程服务器Linux上redis出错解
时间:2020-12-29
-
Intel CPU底层漏洞事件完全详解:包括修复
时间:2020-12-28
-
在不重启的情况下为Vmware Linux客户机添加
时间:2020-12-28
